package org.glow.changgou.seckill.task;


import com.alibaba.fastjson.JSON;
import org.glow.changgou.entity.IdWorker;
import org.glow.changgou.entity.SystemConstants;
import org.glow.changgou.seckill.dao.SeckillGoodsMapper;
import org.glow.changgou.seckill.pojo.SeckillGoods;
import org.glow.changgou.seckill.pojo.SeckillOrder;
import org.glow.changgou.seckill.pojo.SeckillStatus;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;

/**
 * 描述
 *
 * @author glow
 * @version 1.0
 * @package org.glow.changgou.seckill.task *
 * @since 1.0
 */
@Component
public class MultiThreadingCreateOrder {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private Environment env;
    @Resource
    private SeckillGoodsMapper seckillGoodsMapper;

    //创建订单 异步处理 加入一个注解
    @Async
    public void createrOrder(){

        //从队列中获取排队信息
        SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundListOps("SeckillOrderQueue").rightPop();
        Object sgoods = redisTemplate.boundListOps("SeckillGoodsCountList_"+seckillStatus.getGoodsId()).rightPop();
        if(sgoods == null)
        {
            clearQueue(seckillStatus);
            return;
        }
        if(seckillStatus!=null) {
            //测试使用写死
            String time = seckillStatus.getTime();
            Long id = seckillStatus.getGoodsId();//秒杀商品的ID
            String username = seckillStatus.getUsername();

            //1.根据商品的ID 获取秒杀商品的数据

            SeckillGoods seckillGoods
                    = (SeckillGoods) redisTemplate.
                    boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + time)
                    .get(id);
            //2.判断是否有库存  如果 没有  抛出异常 :卖完了
            if (seckillGoods == null || seckillGoods.getStockCount() <= 0) {
                throw new RuntimeException("卖完了");
            }

            //3.如果有库存

            //4.创建一个预订单
            SeckillOrder seckillOrder = new SeckillOrder();
            seckillOrder.setId(idWorker.nextId());//订单的ID
            seckillOrder.setSeckillId(id);//秒杀商品ID
            seckillOrder.setMoney(seckillGoods.getCostPrice());//金额
            seckillOrder.setUserId(username);//登录的用户名
            seckillOrder.setCreateTime(new Date());//创建时间
            seckillOrder.setStatus("0");//未支付
            redisTemplate.boundHashOps(SystemConstants.SEC_KILL_ORDER_KEY).put(username, seckillOrder);



            //5.减库存
            //在redis内修改，避免内存在并发情况下数据不准确
//            seckillGoods.setStockCount(seckillGoods.getStockCount() - 1);
                Long surplusCount = redisTemplate.boundHashOps("SeckiiGoodsCount").increment(id,-1);
                seckillGoods.setStockCount(surplusCount.intValue());
            //6.判断库存是是否为0  如果 是,更新到数据库中,删除掉redis中的秒杀商品
            if (seckillGoods.getStockCount() <= 0) {
                seckillGoodsMapper.updateById(seckillGoods);//数据库的库存更新为0
                redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + time).delete(id);
            } else {
                //设置回redis中
                redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + time).put(id, seckillGoods);

            }
            //7.创建订单成功()


            try {
                System.out.println("开始模拟下单操作=====start====" + new Date() + Thread.currentThread().getName());
                Thread.sleep(10000);
                System.out.println("开始模拟下单操作=====end====" + new Date() + Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //创建订单成功了 修改用户的抢单的信息
            seckillStatus.setOrderId(seckillOrder.getId());
            seckillStatus.setStatus(2);//
            seckillStatus.setMoney(Float.valueOf(seckillOrder.getMoney()));
            //发送延时消息到MQ中
            sendTimerMessage(seckillStatus);
            //重新设置回redis中
            redisTemplate.boundHashOps("UserQueueStatus").put(username,seckillStatus);

        }

    }
    /***
     * 清理用户排队信息
     * @param seckillStatus
     */
    public void clearQueue(SeckillStatus seckillStatus){
        //清理排队标示
        redisTemplate.boundHashOps("UserQueueCount").delete(seckillStatus.getUsername());

        //清理抢单标示
        redisTemplate.boundHashOps("UserQueueStatus").delete(seckillStatus.getUsername());
    }

    /***
     * 发送延时消息到RabbitMQ中
     * @param seckillStatus
     */
    public void sendTimerMessage(SeckillStatus seckillStatus){
        rabbitTemplate.convertAndSend(env.getProperty("mq.pay.queue.seckillordertimerdelay"), (Object) JSON.toJSONString(seckillStatus), new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setExpiration("10000");
                return message;
            }
        });
    }
}
